package com.test36_注解;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * Annotation整合工厂设计模式
 */
public class Demo03_Factory {

    public static void main(String[] args) throws Exception {
        System.out.println(new Message2().echo("www.yootk.com"));
    }
}

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@interface Action2 {
    public String value();
}

/** 实现实例化对象控制的类型 */
@Target(ElementType.CONSTRUCTOR)
@Retention(RetentionPolicy.RUNTIME)
@interface Instance2 {
    public String value();
}

interface IChannel extends AutoCloseable {
    public boolean build();     // 建立通道
}

class InternetChannel implements IChannel {
    @Override
    public boolean build() {
        System.out.println("【InternetChannel】建立互联网通讯通道。");
        return true;
    }

    @Override
    public void close() throws Exception {
        System.out.println("【InternetChannel】关闭互联网通讯通道。");
    }
}

class RadioChannel implements IChannel {
    @Override
    public boolean build() {
        System.out.println("【InternetChannel】建立无线电通讯通道。");
        return true;
    }

    @Override
    public void close() throws Exception {
        System.out.println("【InternetChannel】关闭无线电通讯通道。");
    }
}

/** 编写工厂类 */
class ChannelFactory {
    private ChannelFactory() {
    }

    public static <T> T getInstance(String className) {
        try {   // 实现一个泛型工厂类
            return (T) Class.forName(className).getDeclaredConstructor().newInstance();
        } catch (Exception e) {
            return null;
        }
    }
}

/** 进行消息的发送处理 */
@Action2("com.test28_注解.InternetChannel")
class Message2 {
    private IChannel channel;

    @Instance2("com.test28_注解.ChannelFactory")
    public Message2() throws Exception {
        Action2 actionAnnotation = super.getClass().getAnnotation(Action2.class);   // 获取类上的Annotation
        Instance2 instanceAnnotation = super.getClass().getConstructor().getAnnotation(Instance2.class);
        String factoryClassName = instanceAnnotation.value();
        Class<?> factoryClazz = Class.forName(factoryClassName);
        this.channel = (IChannel) factoryClazz.getMethod("getInstance", String.class).invoke(null, actionAnnotation.value());
    }

    public String echo(String msg) throws Exception {
        String echoMessage = "【ERROR】消息发送失败！";
        if (this.channel.build()) {
            echoMessage = "【ECHO】" + msg;
            this.channel.close();
        }
        return echoMessage;
    }
}
